home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Revolution - Das Atari CD Magazin 1997
/
Revolution - Das Atari CD Magazin 1.iso
/
software
/
anwendng
/
utility
/
cbhd502
/
src
/
m2
/
scsistre.m
< prev
next >
Wrap
Text File
|
1997-01-21
|
12KB
|
392 lines
IMPLEMENTATION MODULE ScsiStreamer;
(****************************************************************************
*
*
* $Source: E:\HM2\LIB\se\rcs\scsistre.m,v $
*
* $Revision: 1.1 $
*
* $Author: S_Engel $
*
* $Date: 1996/02/03 19:34:50 $
*
* $State: Exp $
*
*****************************************************************************
* History:
*
* $Log: scsistre.m,v $
* Revision 1.1 1996/02/03 19:34:50 S_Engel
* Initial revision
*
*
*
****************************************************************************)
(* Systemabhängiges *)
(* IMPLEMENTATION FÜR >>> Hänisch-Modula-2 <<< *)
(* *)
(* Durchgeführt von Steffen Engel *)
(* *)
(*$S- Stack-Checks *)
(*$I- keine Variablen-Initialisierung *)
(*$V- keine arithmetischen Kontrollen *)
(*$T- kein Bereichstest *)
(*$Y- keine Laufzeittests auf RETURN und CASE *)
(* *)
(*----------------------------------------------*)
IMPORT SYSTEM, System;
FROM SYSTEM (* Type *) IMPORT BYTE, ADDRESS,
(* Proc *) ADR, TSIZE;
FROM Portab IMPORT UChar, Char;
(* Standard HM2-Libs *)
(* Eigene Libs *)
(* Projektlibs *)
IMPORT Scsi, ScsiIO;
FROM Scsi IMPORT Cmd6, Cmd10, Cmd12, SetCmd6, SetCmd10, SetCmd12, SetCmd,
BlockLen, MaxDmaLen, LogicalUnit;
(***************************************************************************)
(*- -*)
(*- Sequential Access Devices -*)
(*- -*)
(***************************************************************************)
PROCEDURE Read(TransferLen:SHORTCARD;Adr:ADDRESS; Timeout : LONGCARD) : BOOLEAN;
VAR
Ok : BOOLEAN;
MaxLen : LONGCARD;
SCmd : ScsiIO.tSCSICmd;
BEGIN
Ok:=TRUE;
MaxLen := MaxDmaLen DIV BlockLen;
WHILE Ok AND (TransferLen > MaxLen) DO
VOID(SetCmd6(Cmd6, 008H, 010000H + MaxLen DIV 256, MaxLen MOD 256));
Ok := ScsiIO.In(SetCmd(SCmd, Cmd6, Adr, VAL(LONGCARD, MaxLen) * BlockLen, Timeout * 200)) = 0;
DEC(TransferLen, MaxLen);
Adr := Adr + VAL(LONGCARD, MaxLen) * BlockLen;
END;
VOID(SetCmd6(Cmd6, 008H, 010000H + TransferLen DIV 256, TransferLen MOD 256));
RETURN Ok AND(ScsiIO.In(SetCmd(SCmd, Cmd6, Adr, BlockLen * VAL(LONGCARD, TransferLen), Timeout * 200)) = 0);
END Read;
PROCEDURE ReadNum(VAR TransferLen:SHORTCARD; Adr:ADDRESS; Timeout : LONGCARD) : BOOLEAN;
VAR Ok : BOOLEAN;
Read : SHORTCARD;
MaxLen : LONGCARD;
SCmd : ScsiIO.tSCSICmd;
BEGIN
Ok:=TRUE;
Read := 0;
MaxLen := MaxDmaLen DIV BlockLen;
WHILE Ok AND (TransferLen > MaxLen) DO
VOID(SetCmd6(Cmd6, 008H, 010000H+MaxLen DIV 256, MaxLen MOD 256));
Ok := ScsiIO.In(SetCmd(SCmd, Cmd6, Adr, VAL(LONGCARD, MaxLen) * BlockLen, Timeout * 200)) = 0;
DEC(TransferLen, MaxLen);
INC(Read, MaxLen);
Adr := Adr + VAL(LONGCARD, MaxLen) * BlockLen;
END;
VOID(SetCmd6(Cmd6, 008H, 010000H + TransferLen DIV 256, TransferLen MOD 256));
IF Ok
THEN
Ok := ScsiIO.In(SetCmd(SCmd, Cmd6, Adr, BlockLen * VAL(LONGCARD, TransferLen), Timeout * 200)) = 0;
INC(Read, TransferLen);
END;
TransferLen := Read;
RETURN Ok;
END ReadNum;
PROCEDURE Write(TransferLen:SHORTCARD;Adr:ADDRESS;Timeout : LONGCARD) : BOOLEAN;
VAR Ok : BOOLEAN;
MaxLen : LONGCARD;
SCmd : ScsiIO.tSCSICmd;
BEGIN
Ok:=TRUE;
MaxLen := MaxDmaLen DIV BlockLen;
WHILE Ok AND (TransferLen > MaxLen) DO
VOID(SetCmd6(Cmd6, 00AH, 010000H + MaxLen DIV 256, MaxLen MOD 256));
Ok := ScsiIO.Out(SetCmd(SCmd, Cmd6, Adr, VAL(LONGCARD, MaxLen) * BlockLen, Timeout * 200)) = 0;
DEC(TransferLen, MaxLen);
Adr := Adr + VAL(LONGCARD, MaxLen) * BlockLen;
END;
VOID(SetCmd6(Cmd6, 00AH, 010000H+TransferLen DIV 256, TransferLen MOD 256));
RETURN Ok AND (ScsiIO.Out(SetCmd(SCmd, Cmd6, Adr, BlockLen * VAL(LONGCARD, TransferLen), Timeout * 200)) = 0);
END Write;
PROCEDURE WriteNum(VAR TransferLen:SHORTCARD;Adr:ADDRESS;Timeout : LONGCARD) : BOOLEAN;
VAR
Ok : BOOLEAN;
Written : SHORTCARD;
MaxLen : SHORTCARD;
SCmd : ScsiIO.tSCSICmd;
BEGIN
Ok:=TRUE;
Written := 0;
MaxLen := MaxDmaLen DIV BlockLen;
WHILE Ok AND (TransferLen > MaxLen) DO
VOID(SetCmd6(Cmd6, 00AH, 010000H + MaxLen DIV 256, MaxLen MOD 256));
Ok := ScsiIO.Out(SetCmd(SCmd, Cmd6, Adr, VAL(LONGCARD, MaxLen) * BlockLen, Timeout * 200)) = 0;
DEC(TransferLen, MaxLen);
INC(Written, MaxLen);
Adr := Adr + VAL(LONGCARD, MaxLen) * BlockLen;
END;
VOID(SetCmd6(Cmd6, 00AH, 010000H + TransferLen DIV 256, TransferLen MOD 256));
IF Ok
THEN
INC(Written, TransferLen);
Ok := ScsiIO.Out(SetCmd(SCmd, Cmd6, Adr, BlockLen * VAL(LONGCARD, TransferLen), Timeout * 200)) = 0;
END;
TransferLen := Written;
RETURN Ok;
END WriteNum;
PROCEDURE Erase(TimeoutSeconds : LONGCARD) : BOOLEAN;
VAR
SCmd : ScsiIO.tSCSICmd;
BEGIN
VOID(SetCmd6(Cmd6, 019H,010000H,0));
RETURN ScsiIO.In(SetCmd(SCmd, Cmd6, NIL, 0, TimeoutSeconds * 200)) = 0;
END Erase;
PROCEDURE Load(Imed, Ret, Eot, Load:BOOLEAN;
TimeoutSeconds:LONGCARD) : BOOLEAN;
VAR
SCmd : ScsiIO.tSCSICmd;
BEGIN
VOID(SetCmd6(Cmd6, 01BH,0,0));
WITH Cmd6 DO
IF Imed THEN
LunAdr:=BYTE(VAL(CHAR, LogicalUnit+1));
ELSE
END;
IF Load THEN
Len := 1;
END;
IF Ret THEN
Len := UChar(VAL(CHAR,VAL(SHORTCARD, CHAR(Len))+2));
END;
IF Eot THEN
Flags:=BYTE(080H);
END;
END;
RETURN ScsiIO.In(SetCmd(SCmd, Cmd6, NIL, 0, TimeoutSeconds * 200)) = 0;
END Load;
PROCEDURE WriteFilemark(Imed : BOOLEAN; Number : SHORTCARD; Timeout : LONGCARD) : BOOLEAN;
VAR
SCmd : ScsiIO.tSCSICmd;
BEGIN
VOID(SetCmd6(Cmd6, 010H,0,Number));
IF Imed THEN
Cmd6.Flags:=BYTE(040H);
END;
RETURN ScsiIO.In(SetCmd(SCmd, Cmd6, NIL, 0, Timeout * 200)) = 0;
END WriteFilemark;
PROCEDURE Space(Code : SHORTCARD; Count : LONGINT;
TimeoutSeconds : LONGCARD) : BOOLEAN;
VAR
Ok : BOOLEAN;
SCmd : ScsiIO.tSCSICmd;
BEGIN
WITH Cmd6 DO
Command := (011H);
LunAdr:=BYTE(VAL(CHAR,LogicalUnit + Code MOD 8));
Adr:=VAL(SHORTCARD, LONGCARD(Count) DIV 0100H);
Len := VAL(UChar, LONGCARD(Count) MOD 0100H);
Flags:=BYTE(0);
END;
RETURN ScsiIO.In(SetCmd(SCmd, Cmd6, NIL, 0, TimeoutSeconds * 200)) = 0;
END Space;
PROCEDURE Rewind(Imed : BOOLEAN; TimeoutSeconds : LONGCARD) : BOOLEAN;
VAR
SCmd : ScsiIO.tSCSICmd;
BEGIN
VOID(SetCmd6(Cmd6, 001H,0,0));
IF Imed THEN
Cmd6.LunAdr:=BYTE(VAL(CHAR,LogicalUnit+1));
END;
RETURN ScsiIO.In(SetCmd(SCmd, Cmd6, NIL, 0, TimeoutSeconds * 200)) = 0;
END Rewind;
(*-------------------------------------------------------------------------*)
(*- -*)
(*- Quick File Access -*)
(*- -*)
(*-------------------------------------------------------------------------*)
PROCEDURE SeekBlock(Imed : BOOLEAN;
BlockAdr,TimeoutSeconds : LONGCARD) : BOOLEAN;
VAR
Ok : BOOLEAN;
SCmd : ScsiIO.tSCSICmd;
BEGIN
VOID(SetCmd6(Cmd6, 00CH,VAL(SHORTCARD, BlockAdr DIV 0100H),
VAL(SHORTCARD, BlockAdr MOD 0100H)));
IF Imed THEN
Cmd6.LunAdr:=BYTE(VAL(CHAR,LogicalUnit+1));
END;
RETURN ScsiIO.In(SetCmd(SCmd, Cmd6, NIL, 0, TimeoutSeconds * 200)) = 0;
END SeekBlock;
PROCEDURE RequestBlockAdr(VAR BlockAdr : LONGCARD) : BOOLEAN;
VAR
Ok : BOOLEAN;
SCmd : ScsiIO.tSCSICmd;
BEGIN
VOID(SetCmd6(Cmd6, 002H, 0, 3));
(* Daten in die oberen 3 Bytes von BlockAdr einlesen *)
Ok := ScsiIO.In(SetCmd(SCmd, Cmd6, ADR(BlockAdr), 3, ScsiIO.DefTimeout)) = 0;
(* Daten an richtige Position shiften *)
BlockAdr:=BlockAdr DIV 0100H;
RETURN Ok;
END RequestBlockAdr;
PROCEDURE Locate(BlockAdresstype : BOOLEAN;
ChangePartition : BOOLEAN;
Imed : BOOLEAN;
BlockAdress : LONGCARD;
Partition : SHORTCARD;
TimeoutSeconds : LONGCARD) : BOOLEAN;
TYPE tLoc = RECORD
Command : BYTE;
Lun : BYTE;
Res1 : BYTE;
Adr3 : BYTE;
Adr2 : BYTE;
Adr1 : BYTE;
Adr0 : BYTE;
Res2 : BYTE;
part : BYTE;
Flags : BYTE;
END;
VAR
Cmd : tLoc;
OldTimeout : LONGCARD;
Ok : BOOLEAN;
SCmd : ScsiIO.tSCSICmd;
BEGIN
(* OldTimeout := ScsiIO.GetTimeout();*)
(* ScsiIO.SetTimeout(TimeoutSeconds * 100);*)
(* Kommandoblock zusammensetzen *)
WITH Cmd DO
Command:=BYTE(02BH);
Lun:=BYTE(VAL(CHAR,LogicalUnit));
IF BlockAdresstype
THEN
(* Bit setzen *)
Lun := BYTE(VAL(CHAR,VAL(SHORTCARD, CHAR(Lun)) + 4));
END;
IF ChangePartition
THEN
(* Bit setzen *)
Lun := BYTE(VAL(CHAR,VAL(SHORTCARD, CHAR(Lun)) + 2));
END;
IF Imed
THEN
(* Bit setzen *)
Lun := BYTE(VAL(CHAR,VAL(SHORTCARD, CHAR(Lun)) + 1));
END;
Res1 := BYTE( 0);
Adr3 := BYTE(VAL(CHAR, BlockAdress DIV 01000000H));
Adr2 := BYTE(VAL(CHAR, BlockAdress DIV 010000H MOD 0100H));
Adr1 := BYTE(VAL(CHAR, BlockAdress DIV 0100H MOD 0100H));
Adr0 := BYTE(VAL(CHAR, BlockAdress MOD 0100H));
Res2 := BYTE( 0);
part := BYTE(VAL(CHAR, Partition));
Flags:=BYTE(0);
END;
RETURN ScsiIO.In(SetCmd(SCmd, Cmd, NIL, 0, TimeoutSeconds * 200)) = 0;
(* Ok := ScsiIO.SendCmdDataIn(Cmd, 10, NIL, 0);*)
(* ScsiIO.SetTimeout(OldTimeout);*)
(* RETURN Ok;*)
END Locate;
PROCEDURE ReadPosition( BlockAdresstype : BOOLEAN;
VAR Partition : SHORTCARD;
VAR BlockAdress : LONGCARD) : BOOLEAN;
TYPE tPositionData = RECORD
Flags : BYTE; (* BOP, EOP, Res, Res, Res, BDU, Res, Res *)
part : BYTE;
Res1 : BYTE;
Res2 : BYTE;
FirstLoc : LONGCARD;
LastLoc : LONGCARD;
Res3 : BYTE;
NBlBuff2 : BYTE;
NBlBuff1 : BYTE;
NBlBuff0 : BYTE;
BuffBytes : LONGCARD;
END;
(*$? TSIZE(tPositionData) # 20 : Fragezeichen? *)
VAR
PositionData : tPositionData;
Ok : BOOLEAN;
SCmd : ScsiIO.tSCSICmd;
BEGIN
VOID(SetCmd10(Cmd10, 034H, 0, 0));
IF BlockAdresstype
THEN
(* Bit setzen *)
Cmd10.Lun := BYTE(VAL(CHAR, LogicalUnit + 1));
END;
Ok := ScsiIO.In(SetCmd(SCmd, Cmd10, ADR(PositionData), SIZE(PositionData), ScsiIO.DefTimeout)) = 0;
(* Ok := ScsiIO.SendCmdDataIn(Cmd10, 10, ADR(PositionData), SIZE(PositionData));*)
WITH PositionData DO
Partition := VAL(SHORTCARD, CHAR(part));
BlockAdress := FirstLoc;
END;
RETURN Ok;
END ReadPosition;
BEGIN
END ScsiStreamer.